# coding=utf-8
# author='kungege21'
# date=2023/8/7 14:25
from datetime import date
from enum import Enum
from typing import Optional, List

from fastapi import APIRouter, Query
from fastapi.openapi.models import Response
from fastapi.params import Path, Cookie, Header
from pydantic import BaseModel, Field

app03 = APIRouter()

"""
第三章：路径参数和数字验证
"""


@app03.get('/path/parameters')
def path_params01():
    return {'message': 'This is a message!'}


@app03.get('/path/{parameters}')
def path_params01(parameters: str):  # 函数的顺序就是路由的顺序
    return {'message': parameters}


# 枚举类
class CityName(str, Enum):
    Beijing = "Beijing China"
    Shanghai = "Shanghai China"


@app03.get('/enum/{city}')  # 枚举类型参数
async def latest(city: CityName):
    if city == CityName.Shanghai:
        return {'city_name': city, 'confirmed': 1492, 'death': 2}
    if city == CityName.Beijing:
        return {'city_name': city, 'confirmed': 99, 'death': 0}
    return {'city_name': city, 'latest': 'unknow'}


@app03.get('/files/{file_path:path}')  # 通过路径参数传递文件路径
def filepath(file_path: str):
    return f'The file path is {file_path}'


"""路径参数和验证"""


@app03.get('/path_validate/{num}')
def path_params_validate(  # 路径参数校验，使用...将其标记为必须参数，None或其他默认值无效
        num: int = Path(..., title='Your Number', description='不可描述', ge=1, le=10)
):
    return num


"""查询参数和字符串验证"""


@app03.get('/query')    # 给了默认值就是选填参数
def page_limit(page: int = 1, limit: Optional[int] = None):
    return {'page': page, 'limit': limit}


@app03.get('query/bool/conversion')     # True:yes,on,1  False:no,off,0
def type_conversion(param: bool = False):
    return param


@app03.get('query/validations')
def query_params_validate(      # 使用...标记其为必选参数， default默认值，None可选
        value: str = Query(..., min_length=3, max_length=8, regex='^a'),
        values: List[str] = Query(default=['v1', 'v2'], alias='bie_ming')
):
    return value, values


"""请求体和字段"""


class CityInfo(BaseModel):
    name: str = Field(..., examples=['Beijing'])        # 字段校验
    country: str
    country_code: str = None
    country_population: int = Field(default=800, title='人口数量', description='国家的人口数量')

    class Config:
        json_schema_extra = {
            "example": {
                "name": "shanghai",
                "country": "China",
                "country_code": "CN",
                "country_population": 1400000000
            }
        }


@app03.post('/request_body/city')
def city_info(city: CityInfo):
    print(city.name, city.country)
    return city.model_dump()


@app03.put('/request_body/city/{name}')
def mix_city_info(
        name: str,
        city01: CityInfo,
        city02: CityInfo,       # body可以传入多个
        confirmed: int = Query(ge=0, description='确诊数', default=0),
        death: int = Query(ge=0, description='死亡数', default=0)
):
    if name == "shanghai":
        return {'shanghai': {'confirmed': confirmed, 'death': death}}
    return city01.model_dump(), city02.model_dump()


"""数据格式嵌套的请求体"""


class Data(BaseModel):
    city: List[CityInfo] = None     # 定义数据格式嵌套的请求体
    data: date
    confirmed: int = Field(default=0, ge=0, description='确诊数')
    deaths: int = Field(default=0, ge=0, description='死亡数')
    recovered: int = Field(default=0, ge=0, description='痊愈数')


@app03.put('/request_body/nested')
def nested_models(data: Data):
    print(data)
    return data


"""读取Cookie和Header"""


# @app03.get('/cookie/set')
# def setCookie(response: Response):
#     response.set_cookie('cookie1', '111111')
#     response.set_cookie('cookie2', '22222')
#     response.set_cookie('cookie3', '333333')
#     return {"result": "设置cookie成功"}


@app03.get('/cookie')        # Headers里添加  'Cookie': 'cookie_id=xxxf'   或  'cookie_id1': 'xxxf'
def cookie(cookie_id1: Optional[str] = Cookie(None, description='cookie参数需额外设置或修改'), cookie_id2: Optional[str] = Cookie(None)):
    return {'cookie_id1': cookie_id1, 'cookie_id2': cookie_id2}


@app03.get('/header')       # Headers里添加 user-agent     x-token
def header(user_agent: Optional[str] = Header(None, convert_underscores=True), x_token: List[str] = Header(None)):
    """
    有些HTTP代理和服务器是不允许在请求头中带有下划线的，所以Header提供convert_underscores属性让user_agent变成user-agent
    """
    return {'user_agent': user_agent, 'x_token': x_token}
